package com.ilink.groundservice.service.impl.Skill;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ilink.groundservice.entity.PO.Skill.AiXSkillTree;
import com.ilink.groundservice.entity.PO.Skill.AiXUserSkillProgress;
import com.ilink.groundservice.entity.VO.AiX.AiXSkillTreeResponse;
import com.ilink.groundservice.entity.VO.AiX.AiXSkillNodeResponse;
import com.ilink.groundservice.mapper.Skill.AiXSkillTreeMapper;
import com.ilink.groundservice.mapper.Skill.AiXSkillNodeMapper;
import com.ilink.groundservice.mapper.Skill.AiXUserSkillProgressMapper;
import com.ilink.groundservice.mapper.AiX.AiXTagConnectMapper;
import com.ilink.groundservice.service.Skill.AiXSkillTreeService;
import com.ilink.ilinkapi.dto.ground.AiX.AiXSkillTreeFilterRequest;
import com.ilink.ilinkapi.dto.ground.AiX.AiXSkillTreeInsertRequest;
import com.ilink.ilinkapi.dto.ground.AiX.AiXSkillTreeUpdateRequest;
import com.ilink.ilinkapi.dto.ground.AiX.AiXSkillProgressUpdateRequest;
import com.ilink.ilinkcommon.exception.BizIllegalException;
import com.ilink.ilinkcommon.utils.BeanUtils;
import com.ilink.ilinkcommon.utils.SnowflakeIdGenerator;
import com.ilink.ilinkcommon.service.oss.OssService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class AiXSkillTreeServiceImpl implements AiXSkillTreeService {

    private final AiXSkillTreeMapper skillTreeMapper;
    private final AiXSkillNodeMapper skillNodeMapper;
    private final AiXUserSkillProgressMapper userSkillProgressMapper;
    private final AiXTagConnectMapper tagConnectMapper;
    private final OssService ossService;

    @Override
    public IPage<AiXSkillTreeResponse> getSkillTreeList(AiXSkillTreeFilterRequest request) {
        Page<AiXSkillTreeResponse> page = new Page<>(request.getPage(), request.getSize());
        // 如果有标签筛选，使用标签筛选方法；否则使用原有方法
        IPage<AiXSkillTreeResponse> result;
        if (request.getTag() != null && !request.getTag().trim().isEmpty()) {
            result = skillTreeMapper.selectSkillTreePageByTag(page, request);
        } else {
            result = skillTreeMapper.selectSkillTreePage(page, request);
        }
        
        // 为每个技能树设置标签列表
        result.getRecords().forEach(skillTree -> {
            List<String> tags = skillTreeMapper.selectSkillTreeTags(skillTree.getSkillTreeId());
            skillTree.setTags(tags);
        });
        
        return result;
    }

    @Override
    public AiXSkillTreeResponse getSkillTreeById(Long skillTreeId) {
        if (skillTreeId == null) {
            throw new BizIllegalException("技能树ID不能为空");
        }
        
        AiXSkillTreeResponse response = skillTreeMapper.selectSkillTreeById(skillTreeId);
        if (response == null) {
            throw new BizIllegalException("技能树不存在");
        }
        
        // 设置标签列表
        List<String> tags = skillTreeMapper.selectSkillTreeTags(skillTreeId);
        response.setTags(tags);
        
        // 获取技能节点
        List<AiXSkillNodeResponse> nodes = skillNodeMapper.selectNodesBySkillTreeId(skillTreeId);
        response.setNodes(nodes);
        
        return response;
    }

    @Override
    public AiXSkillTreeResponse getSkillTreeByIdWithProgress(Long skillTreeId, String userId) {
        if (skillTreeId == null) {
            throw new BizIllegalException("技能树ID不能为空");
        }
        if (userId == null) {
            throw new BizIllegalException("用户ID不能为空");
        }
        
        AiXSkillTreeResponse response = skillTreeMapper.selectSkillTreeById(skillTreeId);
        if (response == null) {
            throw new BizIllegalException("技能树不存在");
        }
        
        // 设置标签列表
        List<String> tags = skillTreeMapper.selectSkillTreeTags(skillTreeId);
        response.setTags(tags);
        
        // 获取技能节点及用户进度
        List<AiXSkillNodeResponse> nodes = skillNodeMapper.selectNodesWithProgress(skillTreeId, userId);
        response.setNodes(nodes);
        
        return response;
    }

    @Override
    @Transactional
    public Long insertSkillTree(AiXSkillTreeInsertRequest request) {
        if (request == null) {
            throw new BizIllegalException("请求参数不能为空");
        }
        
        // 使用雪花算法生成技能树ID
        SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(1, 1);
        
        AiXSkillTree skillTree = BeanUtils.copyBean(request, AiXSkillTree.class);
        skillTree.setSkillTreeId(idGenerator.nextId());
        skillTree.setCreatedAt(LocalDateTime.now());
        skillTree.setUpdatedAt(LocalDateTime.now());
        
        // 处理封面图片上传
        if (request.getSkillTreeCover() != null && !request.getSkillTreeCover().isEmpty()) {
            String fileName = "cover_" + System.currentTimeMillis() + "_" + request.getSkillTreeCover().getOriginalFilename();
            String coverUrl = ossService.uploadFileAndGetUrl(request.getSkillTreeCover(), "study-square-migrate", "skill-tree/" + fileName);
            skillTree.setSkillTreeCover(coverUrl);
        }
        
        int result = skillTreeMapper.insert(skillTree);
        if (result <= 0) {
            throw new BizIllegalException("技能树创建失败");
        }
        
        return skillTree.getSkillTreeId();
    }

    @Override
    @Transactional
    public void updateSkillTree(AiXSkillTreeUpdateRequest request) {
        if (request == null || request.getSkillTreeId() == null) {
            throw new BizIllegalException("请求参数不能为空");
        }
        
        AiXSkillTree existingSkillTree = skillTreeMapper.selectById(request.getSkillTreeId());
        if (existingSkillTree == null) {
            throw new BizIllegalException("技能树不存在");
        }
        
        AiXSkillTree skillTree = BeanUtils.copyBean(request, AiXSkillTree.class);
        skillTree.setUpdatedAt(LocalDateTime.now());
        
        // 处理封面图片上传
        if (request.getSkillTreeCover() != null && !request.getSkillTreeCover().isEmpty()) {
            String fileName = "cover_" + System.currentTimeMillis() + "_" + request.getSkillTreeCover().getOriginalFilename();
            String coverUrl = ossService.uploadFileAndGetUrl(request.getSkillTreeCover(), "study-square-migrate", "skill-tree/" + fileName);
            skillTree.setSkillTreeCover(coverUrl);
        }
        
        int result = skillTreeMapper.updateById(skillTree);
        if (result <= 0) {
            throw new BizIllegalException("技能树更新失败");
        }
    }

    @Override
    @Transactional
    public void deleteSkillTree(Long skillTreeId) {
        if (skillTreeId == null) {
            throw new BizIllegalException("技能树ID不能为空");
        }
        
        AiXSkillTree skillTree = skillTreeMapper.selectById(skillTreeId);
        if (skillTree == null) {
            throw new BizIllegalException("技能树不存在");
        }
        
        // 删除相关的技能节点和用户进度记录
        // 这里可以根据实际需求决定是否级联删除
        
        int result = skillTreeMapper.deleteById(skillTreeId);
        if (result <= 0) {
            throw new BizIllegalException("技能树删除失败");
        }
    }

    @Override
    @Transactional
    public void updateSkillTreeCover(MultipartFile file, Long skillTreeId) {
        if (file == null || file.isEmpty()) {
            throw new BizIllegalException("封面文件不能为空");
        }
        if (skillTreeId == null) {
            throw new BizIllegalException("技能树ID不能为空");
        }
        
        AiXSkillTree skillTree = skillTreeMapper.selectById(skillTreeId);
        if (skillTree == null) {
            throw new BizIllegalException("技能树不存在");
        }
        
        String fileName = "cover_" + System.currentTimeMillis() + "_" + file.getOriginalFilename();
        String coverUrl = ossService.uploadFileAndGetUrl(file, "study-square-migrate", "skill-tree/" + fileName);
        skillTree.setSkillTreeCover(coverUrl);
        skillTree.setUpdatedAt(LocalDateTime.now());
        
        int result = skillTreeMapper.updateById(skillTree);
        if (result <= 0) {
            throw new BizIllegalException("技能树封面更新失败");
        }
    }

    @Override
    public AiXSkillTreeResponse getUserSkillTreeProgress(Long skillTreeId, String userId) {
        return getSkillTreeByIdWithProgress(skillTreeId, userId);
    }

    @Override
    @Transactional
    public void updateUserSkillProgress(AiXSkillProgressUpdateRequest request, String userId) {
        if (request == null || userId == null) {
            throw new BizIllegalException("请求参数不能为空");
        }
        
        // 查询现有进度记录
        AiXUserSkillProgress existingProgress = userSkillProgressMapper.selectProgressByUserAndNode(
            userId, request.getSkillTreeId(), request.getNodeId());
        
        if (existingProgress != null) {
            // 更新现有记录
            existingProgress.setStatus(request.getStatus());
            existingProgress.setCompletionRate(request.getCompletionRate());
            existingProgress.setCurrentPoints(request.getCurrentPoints());
            existingProgress.setTimeSpent(request.getTimeSpent());
            existingProgress.setNotes(request.getNotes());
            existingProgress.setUpdatedAt(LocalDateTime.now());
            
            if ("completed".equals(request.getStatus())) {
                existingProgress.setCompleteTime(LocalDateTime.now());
            }
            
            userSkillProgressMapper.updateById(existingProgress);
        } else {
            // 创建新记录
            SnowflakeIdGenerator progressIdGenerator = new SnowflakeIdGenerator(1, 2);
            
            AiXUserSkillProgress progress = BeanUtils.copyBean(request, AiXUserSkillProgress.class);
            progress.setProgressId(progressIdGenerator.nextId());
            progress.setUserId(userId);
            progress.setStartTime(LocalDateTime.now());
            progress.setCreatedAt(LocalDateTime.now());
            progress.setUpdatedAt(LocalDateTime.now());
            
            if ("completed".equals(request.getStatus())) {
                progress.setCompleteTime(LocalDateTime.now());
            }
            
            userSkillProgressMapper.insert(progress);
        }
    }

    @Override
    @Transactional
    public void resetUserSkillProgress(Long skillTreeId, String userId) {
        if (skillTreeId == null || userId == null) {
            throw new BizIllegalException("参数不能为空");
        }
        
        // 删除用户在该技能树的所有进度记录
        LambdaQueryWrapper<AiXUserSkillProgress> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AiXUserSkillProgress::getUserId, userId)
               .eq(AiXUserSkillProgress::getSkillTreeId, skillTreeId);
        
        userSkillProgressMapper.delete(wrapper);
    }

    @Override
    public List<AiXSkillTreeResponse> getPopularSkillTrees(Integer limit) {
        if (limit == null || limit <= 0) {
            limit = 10;
        }
        List<AiXSkillTreeResponse> results = skillTreeMapper.selectPopularSkillTrees(limit);
        
        // 为每个技能树设置标签列表
        results.forEach(skillTree -> {
            List<String> tags = skillTreeMapper.selectSkillTreeTags(skillTree.getSkillTreeId());
            skillTree.setTags(tags);
        });
        
        return results;
    }

    @Override
    public List<AiXSkillTreeResponse> getUserSkillTrees(String userId, Long areaId) {
        if (userId == null) {
            throw new BizIllegalException("用户ID不能为空");
        }
        List<AiXSkillTreeResponse> results = skillTreeMapper.selectUserSkillTrees(userId, areaId);
        
        // 为每个技能树设置标签列表
        results.forEach(skillTree -> {
            List<String> tags = skillTreeMapper.selectSkillTreeTags(skillTree.getSkillTreeId());
            skillTree.setTags(tags);
        });
        
        return results;
    }

    @Override
    public List<String> getSkillTreeTags(Long areaId) {
        return tagConnectMapper.getSkillTreeTags(areaId, 8);
    }

    @Override
    public List<String> getAllSkillTreeTags(Long areaId) {
        return tagConnectMapper.getAllSkillTreeTags(areaId);
    }
} 